<?php

namespace App\Services;

use App\Models\AdminLog;
use App\Models\AdminLogItem;
use App\Models\AdminMenu;
use App\Models\AgentLog;
use App\Models\Hall;
use App\Models\MasterLog;
use App\Models\MasterLogItem;
use App\Models\MasterMenu;
use App\Models\UserLog;
use App\Models\AdminLogExtend;
use common\enum\AdminLogEnum;
use common\enum\AgentLogEnum;
use common\enum\CommonEnum;
use common\enum\MasterLogEnum;
use common\enum\UserLogEnum;
use common\utils\SysCode;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Request;

class MasterLogService
{
    const DEFAULT_STATUS = 1;
    CONST KEY = 0;

    /**添加总后台操作日志
     * @param $data
     * @return int
     */
    public static function addMasterLog($data)
    {
        $ip = !isset($data['ip']) ? self::getIp() : $data['ip'];
        $adminInfo = Auth::user();
        $model = new MasterLog();
        $model->master_user_id = !empty($adminInfo) ? Auth::user()->id : '0';
        $model->master_username = !empty($adminInfo) ? Auth::user()->username : '';
        $model->edited_user_id = isset($data['edited_user_id']) ? $data['edited_user_id'] : '0';
        $model->edited_username = isset($data['edited_username']) ? $data['edited_username'] : '';
        $model->operate_type = $data['operate_type'];
        $model->log_type = $data['log_type'];
        $model->log_value = isset($data['log_value']) ? $data['log_value'] : '';
        $model->log_ip = $ip;
        $model->status = self::DEFAULT_STATUS;
        if (!$model->save()) {
            Log::error('操作日志参数缺失' . json_encode($model->toArray()));
            return SysCode::FAILED;
        }
        return SysCode::OK;
    }

    public static function writeMasterLog($itemId, $status, $remark = '', array $data = [])
    {
        $itemModel = MasterLogItem::where(['id' => $itemId])->first();
        if (!$itemModel) {
            Log::info('MasterLogItem error');
            return true;
        }
        $itemData = $itemModel->toArray();
        $userInfo = Auth::user();
        $addDate  = [
            'module_id'     => $itemData['module_id'],
            'menu_id'       => $itemData['menu_id'],
            'item_id'       => $itemData['id'],
            'old'           => !empty($data['old']) ? json_encode($data['old'], JSON_UNESCAPED_UNICODE) : '',
            'new'           => !empty($data['new']) ? json_encode($data['new'], JSON_UNESCAPED_UNICODE) : '',
            'remark'        => $remark,
            'target_id'     => !empty($data['target_id']) ? $data['target_id'] : '',
            'target_name'   => !empty($data['target_name']) ? $data['target_name'] : '',
            'operator_id'   => !empty($userInfo) ? $userInfo['id'] : 0,
            'operator_name' => !empty($userInfo) ? $userInfo['username'] : '',
            'log_ip'        => Request::ip(),
            'status'        => $status,
        ];
        $masterId = MasterLog::insertGetId($addDate);
        if (!$masterId) {
            Log::info('insert masterLog error error');
            return true;
        }
    }

    /**
     * 获取厅主后台日志列表
     * @param $params
     * @return array
     * @throws \App\Exceptions\CustomException
     */
    public static function getAdminLogList($params)
    {
        $select = ['id', 'hall_id', 'operator_name', 'target_name', 'module_id', 'menu_id', 'item_id', 'remark', 'log_ip', 'status', 'created_at','new','old'];
        $sqlObj = AdminLog::select($select);
        if (!empty($params)) {
            self::adminCriteria($sqlObj, $params);
        }
        $page      = !empty($params['page']) ? $params['page'] : CommonEnum::PAGE_DEFAULT;
        $page_size = !empty($params['page_size']) ? $params['page_size'] : CommonEnum::PAGE_SIZE_TWENTY;
        $sqlObj->orderBy('created_at', 'desc');
        $result = get_page_data($sqlObj, $page, $page_size);
        if (!empty($result['list'])) {
            $result['list'] = self::adminConvert($result['list']);
        }
        return $result;
    }

    /**
     * 厅主日志的《ADMIN》搜索条件
     * @param $model
     * @param $values
     * @throws \App\Exceptions\CustomException
     */
    public static function adminCriteria($model, $values)
    {
        if (!empty($values['date_begin']) && !empty($params['date_end']) && $values['date_end'] > $values['date_begin']) {
            error_exit(SysCode::SYSTEM_BEGIN_END_TIME_ERROR);
        }
        if (!empty($values['hall_id'])) {
            $model->where(['hall_id' => $values['hall_id']]);
        }
        if (!empty($values['operator_name'])) {
            $model->where(['operator_name' => trim($values['operator_name'])]);
        }
        if (!empty($values['target_name'])) {
            $model->where(['target_name' => trim($values['target_name'])]);
        }
        if (!empty($values['log_ip'])) {
            $model->where(['log_ip' => trim($values['log_ip'])]);
        }
        if (!empty($values['status']) || isset($values['status'])) {
            $model->where(['status' => $values['status']]);
        }
        if (!empty($values['module_id'])) {
            $model->where(['module_id' => $values['module_id']]);
        }
        if (!empty($values['menu_id'])) {
            $model->where(['menu_id' => $values['menu_id']]);
        }
        if (!empty($values['item_id'])) {
            $model->where(['item_id' => $values['item_id']]);
        }
        if (!empty($values['date_begin'])) {
            $model->where('created_at', '>=', self::handleDate($values['date_begin']));
        }
        if (!empty($values['date_end'])) {
            $model->where('created_at', '<=', self::handleDate($values['date_end'], true));
        }
    }
    /**
     * admin模块id、子模块id、操作id转换name
     * @param $logArray
     * @return array
     */
    public static function adminConvert($logArray)
    {
        $adminMenu = AdminMenu::select(['id', 'level', 'parent', 'name'])->get()->toArray();;
        $adminLogItem = AdminLogItem::select(['id', 'name', 'module_id', 'menu_id'])->get()->toArray();
        return self::turnValue($logArray, $adminMenu, $adminLogItem,'admin');
    }

    /**
     * 三级联动
     * @return array
     */
    public static function threeLevelLinkList(int $type)
    {
        $result = [];
        if ($type == MasterLogEnum::ADMIN) {//厅主三级联动
            $hallMenuNameList = AdminMenu::select()->get()->toArray();
            $itemListData     = AdminLogItem::select()->get()->toArray();
        } elseif ($type == MasterLogEnum::MASTER) {//总后台三级联动
            $hallMenuNameList = MasterMenu::select()->get()->toArray();
            $itemListData     = MasterLogItem::select()->get()->toArray();
        }
        $nameList = array_combine(array_column($hallMenuNameList, 'id'), array_column($hallMenuNameList, 'name'));
        if (!empty($itemListData)) {
            foreach ($itemListData as $k => $v) {
                $result[$v['module_id']]['label']                                 = isset($nameList[$v['module_id']]) ? $nameList[$v['module_id']] : "";
                $result[$v['module_id']]['value']                                 = $v['module_id'];
                $itemList                                                         = [];
                $itemList['value']                                                = $v['id'];
                $itemList['label']                                                = $v['name'];
                $result[$v['module_id']]['menulist'][$v['menu_id']]['chidlist'][] = $itemList;
                $result[$v['module_id']]['menulist'][$v['menu_id']]['label']      = isset($nameList[$v['menu_id']]) ? $nameList[$v['menu_id']] : "";
                $result[$v['module_id']]['menulist'][$v['menu_id']]['value']      = $v['menu_id'];
            }
        }
        foreach ($result as $kl => $zz) {
            if (isset($zz['menulist'])) {
                $result[$kl]['menulist'] = array_values($zz['menulist']);
            }
        }
        return array_values($result);
    }

    /**
     * 获取总后台操作日志列表
     * @param $params
     * @return array
     * @throws \App\Exceptions\CustomException
     */
    public static function getMasterLogList($params)
    {
        $select = ['id', 'operator_name', 'target_name', 'old', 'new', 'module_id', 'menu_id', 'item_id', 'remark', 'log_ip', 'status', 'created_at',];
        $sqlObj = MasterLog::select($select);
        if (!empty($params)) {
            self::masterCriteria($sqlObj, $params);
        }
        $page      = !empty($params['page']) ? $params['page'] : CommonEnum::PAGE_DEFAULT;
        $page_size = !empty($params['page_size']) ? $params['page_size'] : CommonEnum::PAGE_SIZE_TWENTY;
        $sqlObj->orderBy('created_at', 'desc');
        $result = get_page_data($sqlObj, $page, $page_size);
        if (!empty($result['list'])) {
            $result['list'] = self::masterConvert($result['list']);
        }
        return $result;
    }

    /**
     * 总后台日志详情
     * @param $masterId
     * @param $itemId
     * @return mixed
     * @throws \App\Exceptions\CustomException
     */
    public static function getMasterLoginfo($masterId, $itemId)
    {
        $masterData = MasterLog::where(['id' => $masterId])->first();
        if (!$masterData) {
            error_exit(SysCode::LOG_WRITE_VIEW_ERROR);
        }
        if($masterData['item_id'] != $itemId){
            error_exit(SysCode::LOG_WRITE_ITEM_ID_ERROR);
        }
        $data = $masterData;
        $list = [];
        $old  = [];
        $new  = [];
        switch (MasterLogEnum::INFO_TYPE[$itemId]) {
            case MasterLogEnum::TYPE_ONE:
            case MasterLogEnum::TYPE_TWO://type为2无对比只有new数据
                if (in_array($itemId, MasterLogEnum::INFO_DATA_TYPE_OBJ)) {
                    $list = !empty($masterData['new']) ? self::handleData(json_decode($masterData['new'], true)) : '';
                } elseif (in_array($itemId, MasterLogEnum::INFO_DATA_TYPE_ARRAY)) {
                    $list = !empty($masterData['new']) ? json_decode($masterData['new'], true) : '';
                }
                break;
            case MasterLogEnum::TYPE_THREE://type为3有对比，有old数据和new数据
                if (in_array($itemId, MasterLogEnum::INFO_DATA_TYPE_OBJ)) {
                    $list = !empty($masterData['new']) ? self::handleData(json_decode($masterData['new'], true)) : '';
                    $old  = !empty($masterData['old']) ? self::handleData(json_decode($masterData['old'], true)) : '';
                    $new  = !empty($masterData['new']) ? self::handleData(json_decode($masterData['new'], true)) : '';
                } elseif (in_array($itemId, MasterLogEnum::INFO_DATA_TYPE_ARRAY)) {
                    $list = !empty($masterData['new']) ? json_decode($masterData['new'], true) : '';
                    $old  = !empty($masterData['old']) ? json_decode($masterData['old'], true) : '';
                    $new  = !empty($masterData['new']) ? json_decode($masterData['new'], true) : '';
                }
                break;
            case MasterLogEnum::TYPE_FOUR://type为4，角色管理特殊处理
                $list = !empty($masterData['new']) ? json_decode($masterData['new'], true) : '';
                $old  = !empty($masterData['old']) ? json_decode($masterData['old'], true) : '';
                $new  = !empty($masterData['new']) ? json_decode($masterData['new'], true) : '';
                break;
            default:
        }
        $data['title'] = !empty(MasterLogEnum::LOG_DETAIL_LIST[$itemId]) ? MasterLogEnum::LOG_DETAIL_LIST[$itemId] : '';
        $data['type']  = !empty(MasterLogEnum::INFO_TYPE[$itemId]) ? MasterLogEnum::INFO_TYPE[$itemId] : "";
        $data['list']  = $list;
        $data['old']   = $old;
        $data['new']   = $new;
        return $data;
    }

    //日志详情
    public static function logDetail($id, $itemId)
    {
        $logdetail      = AdminLog::where(['id' => $id, 'item_id' => $itemId])->first();
        if (!$logdetail) {
            error_exit(SysCode::LOG_WRITE_VIEW_ERROR);
        }
        $logdetail      = $logdetail->toArray();
        $itemData       = AdminLogEnum::ADMIN_ITEM_IDS;
        $detailList     = AdminLogEnum::LOG_DETAIL_LIST;
        $detailListType = AdminLogEnum::LOG_DETAIL_LIST_TYPE;
        $keylist        = array_keys($detailList);
        if (!in_array($itemId, $keylist) || empty($logdetail)) {
            return [];
        }
        $logdetail['title'] = $detailList[$itemId];
        $logdetail['type']  = isset($detailListType[$itemId]) ? $detailListType[$itemId] : 1;
        $list               = [];
        switch ($itemId) {
            case $itemData['user_kickoff_batch']:
            case $itemData['user_edit']:
                $list              = json_decode($logdetail['new'], true);
                $logdetail['list'] = $list;
                break;
            case $itemData['admin_role_add']:
            case $itemData['admin_role_edit']:
            case $itemData['admin_role_delete']:
                $logDetail = AdminLogExtend::where(['admin_log_id' => $id])->first();
                $logdetail['new'] = !empty($logDetail['new']) ? json_decode($logDetail['new'], true) : [];
                $logdetail['old'] = !empty($logDetail['old']) ? json_decode($logDetail['old'], true) : [];
                $list = !empty($logDetail['new']) ? json_decode($logDetail['new'], true) : [];
                $logdetail['list'] = $list;
                break;
            default:
                $list              = json_decode($logdetail['new'], true);
                $logdetail['list'] = $list;
                $logdetail['new']  = json_decode($logdetail['new'], true);
                $logdetail['old']  = json_decode($logdetail['old'], true);
        }
        return $logdetail;
    }

    public static function handleData($arr)
    {
        $data = [];
        foreach ($arr as $key => $val) {
            $data[] = [$key => $val];
        }
        return $data;
    }


    /**
     * master模块id、子模块id、操作id转换name
     * @param $logArray
     * @return array
     */
    public static function masterConvert($logArray)
    {
        $menu = MasterMenu::select(['id', 'level', 'parent', 'name'])->get()->toArray();;
        $item = MasterLogItem::select(['id', 'name', 'module_id', 'menu_id'])->get()->toArray();
        return self::turnValue($logArray, $menu, $item,'master');
    }

    /**
     * 总后台日志搜索条件
     * @param $model
     * @param $values
     * @throws \App\Exceptions\CustomException
     */
    public static function masterCriteria($model, $values)
    {
        if (!empty($values['date_begin']) && !empty($params['date_end']) && $values['date_end'] > $values['date_begin']) {
            error_exit(SysCode::SYSTEM_BEGIN_END_TIME_ERROR);
        }
        if (!empty($values['operator_name'])) {
            $model->where(['operator_name' => trim($values['operator_name'])]);
        }

        if (!empty($values['target_name'])) {
            $model->where(['target_name' => trim($values['target_name'])]);
        }
        if (!empty($values['log_ip'])) {
            $model->where(['log_ip' => trim($values['log_ip'])]);
        }
        if (!empty($values['status']) || isset($values['status'])) {
            $model->where(['status' => $values['status']]);
        }
        if (!empty($values['module_id'])) {
            $model->where(['module_id' => $values['module_id']]);
        }
        if (!empty($values['menu_id'])) {
            $model->where(['menu_id' => $values['menu_id']]);
        }
        if (!empty($values['item_id'])) {
            $model->where(['item_id' => $values['item_id']]);
        }
        if (!empty($values['date_begin'])) {
            $model->where('created_at', '>=', self::handleDate($values['date_begin']));
        }
        if (!empty($values['date_end'])) {
            $model->where('created_at', '<=', self::handleDate($values['date_end'], true));
        }
    }

    /**
     * 获取会员操作日志列表
     * @param $params
     * @return array
     */
    public static function getUserLogList($params)
    {
        $select = ['id', 'hall_id', 'username', 'type_name', 'remark', 'ip', 'created_at', 'status', 'device'];
        $sqlObj = UserLog::select($select);
        if (!empty($params)) {
            self::userCriteria($sqlObj, $params);
        }
        $page      = !empty($params['page']) ? $params['page'] : CommonEnum::PAGE_DEFAULT;
        $page_size = !empty($params['page_size']) ? $params['page_size'] : CommonEnum::PAGE_SIZE_TWENTY;
        $sqlObj->orderBy('created_at', 'desc');
        $result = get_page_data($sqlObj, $page, $page_size);
        if (!empty($result['list'])) {
            $hall = self::getHall();
            foreach ($result['list'] as &$val) {
                $val['status_name'] = MasterLogEnum::STATUS_NAME[$val['status']];
                $val['device']      = MasterLogEnum::DEVICE[$val['device']];
                $val['hall_name']   = $hall[$val['hall_id']]['company_name'];
            }
        }
        return $result;
    }

    public static function userCriteria($model, $values)
    {
        if (!empty($values['date_begin']) && !empty($params['date_end']) && $values['date_end'] > $values['date_begin']) {
            error_exit(SysCode::SYSTEM_BEGIN_date_end_ERROR);
        }
        if (!empty($values['hall_id'])) {
            $model->where(['hall_id' => $values['hall_id']]);
        }
        if (!empty($values['device']) || isset($values['device'])) {
            $model->where(['device' => $values['device']]);
        }
        if (!empty($values['username'])) {
            $model->where(['username' => trim($values['username'])]);
        }
        if (!empty($values['ip'])) {
            $model->where(['ip' => trim($values['ip'])]);
        }
        if (!empty($values['type'])) {
            $model->where(['type' => $values['type']]);
        }
        if (!empty($values['status']) || isset($values['status'])) {
            $model->where(['status' => $values['status']]);
        }
        if (!empty($values['date_begin'])) {
            $model->where('created_at', '>=', self::handleDate($values['date_begin']));
        }
        if (!empty($values['date_end'])) {
            $model->where('created_at', '<=', self::handleDate($values['date_end'], true));
        }
    }


    /**
     * 获取代理操作日志列表
     * @param $params
     * @return array
     */
    public static function getAgentLogList($params)
    {
        $select = ['id', 'hall_id','agent_name', 'agent_type', 'type_name', 'remark', 'ip', 'created_at', 'status', 'domain'];
        $sqlObj = AgentLog::select($select);
        if (!empty($params)) {
            self::agentCriteria($sqlObj, $params);
        }
        $sqlObj->orderBy('created_at', 'desc');
        $page      = !empty($params['page']) ? $params['page'] : CommonEnum::PAGE_DEFAULT;
        $page_size = !empty($params['page_size']) ? $params['page_size'] : CommonEnum::PAGE_SIZE_TWENTY;
        $result    = get_page_data($sqlObj, $page, $page_size);
        if (!empty($result['list'])) {
            $hall = self::getHall();
            foreach ($result['list'] as &$v) {
                $v['status_name'] = MasterLogEnum::STATUS_NAME[$v['status']];
                $v['agent_type'] = MasterLogEnum::AGENT_TYPE[$v['agent_type']];
                $v['hall_name']   = $hall[$v['hall_id']]['company_name'];
            }
        }
        return $result;
    }

    public static function agentCriteria($model, $values)
    {
        if (!empty($values['date_begin']) && !empty($params['date_end']) && $values['date_end'] > $values['date_begin']) {
            error_exit(SysCode::SYSTEM_BEGIN_END_TIME_ERROR);
        }
        if (!empty($values['hall_id'])) {
            $model->where(['hall_id' => $values['hall_id']]);
        }
        if (!empty($values['agent_name'])) {
            $model->where(['agent_name' => trim($values['agent_name'])]);
        }
        if (!empty($values['ip'])) {
            $model->where(['ip' => trim($values['ip'])]);
        }
        if (!empty($values['type'])) {
            $model->where(['type' => $values['type']]);
        }
        if (!empty($values['status']) || isset($values['status'])) {
            $model->where(['status' => $values['status']]);
        }
        if (!empty($values['agent_type']) || isset($values['agent_type'])) {
            $model->where(['agent_type' => $values['agent_type']]);
        }
        if (!empty($values['date_begin'])) {
            $model->where('created_at', '>=', self::handleDate($values['date_begin']));
        }
        if (!empty($values['date_end'])) {
            $model->where('created_at', '<=', self::handleDate($values['date_end'], true));
        }
    }


    /**
     * 数据转换;将模块id、子模块id、操作类型id，转换为name
     * @param $logArray
     * @return array
     */
    public static function turnValue($logArray, $menu, $itom, $type = '')
    {
        $logData = [];
        $menu    = array_column($menu, null, 'id');
        $itom    = array_column($itom, null, 'id');
        foreach ($logArray as &$val) {
            $val['module_name'] = !empty($menu[$val['module_id']]['name']) ? $menu[$val['module_id']]['name'] : '';
            $val['menu_neme']   = !empty($menu[$val['menu_id']]['name']) ? $menu[$val['menu_id']]['name'] : '';
            $val['item_neme']   = !empty($itom[$val['item_id']]['name']) ? $itom[$val['item_id']]['name'] : '';
            $val['status_name'] = MasterLogEnum::STATUS_NAME[$val['status']];
            if (!empty($val['hall_id'])) {//将厅主id，转换为name
                $hall             = self::getHall();
                $val['hall_name'] = $hall[$val['hall_id']]['company_name'];
            }
            //判定是否有详情
            if (!empty($val['old']) || !empty($val['new'])) {
                $val['log_type'] = MasterLogEnum::SINGLE_VIEW;
            } else {
                $val['log_type'] = MasterLogEnum::NO_VIEW;
            }
            //判定是否有双详情
            if($type == 'master'){
                if(in_array($val['item_id'],MasterLogEnum::DOUBLE_VIEW_ARRAY)){
                    $val['log_type'] = MasterLogEnum::DOUBLE_VIEW;
                }
            }elseif ($type == 'admin'){
                $val['log_type'] = isset($val['old']) && $val['old'] == "[]" && isset($val['new']) && $val['new'] == "[]" ? AdminLogEnum::NO_VIEW : AdminLogEnum::SINGLE_VIEW;
                if(in_array($val['item_id'],AdminLogEnum::DOUBLE_VIEW_ARRAY)){
                    $val['log_type'] = MasterLogEnum::DOUBLE_VIEW;
                }elseif(in_array($val['item_id'],AdminLogEnum::ADMIN_LOG_DISPLAY_SINGLE)){
                    $val['log_type'] = MasterLogEnum::SINGLE_VIEW;
                }
            }
            $logData[]          = $val;
        }
        return $logData;
    }

    public static function getHall()
    {
        $hall = Hall::select(['id', 'company_name'])->get()->toArray();
        return array_column($hall, null, 'id');

    }

    /**
     * 下拉菜单列表
     * @param $type
     * @return array|mixed
     */
    public static function distribute($type)
    {
        switch ($type) {
            //厅主日志下拉搜索条件
            case MasterLogEnum::ADMIN:
                return self::adminSearch();
                break;
            //总后台日志下拉搜索条件
            case MasterLogEnum::MASTER:
                return self::masterSearch();
                break;
            //会员日志下拉搜索条件
            case MasterLogEnum::USER:
                return self::userSearch();
                break;
            //代理日志下拉搜索条件
            case MasterLogEnum::AGENT:
                return self::agentSearch();
                break;
        }
    }

    public static function adminSearch()
    {
        $data           = [];
        $data['status'] = self::dataConversion(MasterLogEnum::STATUS_NAME);
        return $data;
    }

    public static function masterSearch()
    {
        $data           = [];
        $data['status'] = self::dataConversion(MasterLogEnum::STATUS_NAME);
        return $data;
    }

    public static function userSearch()
    {
        $data           = [];
        $data['type']   = self::dataConversion(UserLogEnum::$userOpTypes);
        $data['device'] = self::dataConversion(MasterLogEnum::DEVICE);
        $data['status'] = self::dataConversion(MasterLogEnum::STATUS_NAME);
        return $data;
    }

    public static function agentSearch()
    {
        $data['type']       = self::dataConversion(UserLogEnum::$agentOpTypes);
        $data['status']     = self::dataConversion(MasterLogEnum::STATUS_NAME);
        $data['agent_type'] = self::dataConversion(MasterLogEnum::AGENT_TYPE);
        return $data;
    }

    /**
     * 数据格式转换
     * @param array $arrayData
     * @return array
     */
    public static function dataConversion(array $arrayData)
    {
        $data = [];
        $i    = self::KEY;
        foreach ($arrayData as $key => $value) {
            $data[$i]['label'] = $value;
            $data[$i]['value'] = $key;
            $i++;
        }
        return $data;
    }

    /**
     * 搜索时间处理
     * @param $date
     * @param bool $choice
     * @return false|string
     */
    public static function handleDate($date, $choice = false)
    {
        if (!$choice) {
            return date('Y-m-d H:i:s', strtotime($date));
        } else {
            return date('Y-m-d H:i:s', strtotime($date) + 86400 - 1);
        }
    }


}
